package com.vmove.childtrain.activity;

import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.RadioGroup;
import android.widget.TextView;

import com.jaygoo.widget.OnRangeChangedListener;
import com.jaygoo.widget.RangeSeekBar;
import com.vmove.childtrain.R;
import com.vmove.childtrain.common.BaseSerialActivity;
import com.vmove.childtrain.common.Constants;
import com.vmove.childtrain.db.dao.LightDao;
import com.vmove.childtrain.db.entity.Light;
import com.vmove.childtrain.domain.IdAndStep;
import com.vmove.childtrain.fragment.DegreeDialog_lesson1;
import com.vmove.childtrain.protocol.CommandType;
import com.vmove.childtrain.protocol.LightCMD;
import com.vmove.childtrain.protocol.detail.LightCMD_Close;
import com.vmove.childtrain.protocol.detail.LightCMD_Close_All;
import com.vmove.childtrain.protocol.detail.LightCMD_Open;
import com.vmove.childtrain.utils.TimeUtils;
import com.vmove.childtrain.utils.ToastUtils;
import com.vmove.childtrain.utils.UIUtils;
import com.vmove.childtrain.view.MyCheckBox;
import com.vmove.childtrain.view.Panel;
import com.vmove.childtrain.view.interpolator.EasingType;
import com.vmove.childtrain.view.interpolator.ExpoInterpolator;
import com.vmove.childtrain.view.media.PlayView;

import java.sql.SQLException;
import java.util.List;
import java.util.Random;
import java.util.Vector;

import androidx.fragment.app.FragmentManager;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

/**
 * 第一课
 * 判断lightId和步骤码
 */
public class Lesson1Activity extends BaseLessonActivity {

    /**
     * 课程1 ic_lesson1
     * 颜色 1 同时亮8 时间2分钟
     */
    @BindView(R.id.cb_lightNum)
    MyCheckBox cbLightNum;
    @BindView(R.id.cb_lightColor)
    MyCheckBox cbLightColor;
    @BindView(R.id.cb_userNum)
    MyCheckBox cbUserNum;
    @BindView(R.id.cb_time)
    MyCheckBox cbTime;
    @BindView(R.id.cb_stepNum)
    MyCheckBox cbStepNum;

    @BindView(R.id.seekbar_lightNum)
    RangeSeekBar seekbarLightNum;
    @BindView(R.id.seekbar_userNum)
    RangeSeekBar seekbarUserNum;
    @BindView(R.id.seekbar_time)
    RangeSeekBar seekbarTime;
    @BindView(R.id.seekbar_stepNum)
    RangeSeekBar seekbarStepNum;

    @BindView(R.id.rg_color)
    RadioGroup rgColor;
    @BindView(R.id.tv_timeCountDown)
    TextView tvTimeCountDown;
    @BindView(R.id.playView)
    PlayView playView;
    @BindView(R.id.ib_show)
    ImageButton ibShow;


    //----------属性设置 start-------
    @BindView(R.id.rightPanel)
    Panel panel;
    @BindView(R.id.seekbar_lightBrightness)
    RangeSeekBar seekbarLightBrightness;
    @BindView(R.id.rg_color_after)
    RadioGroup rgColorAfter;
    @BindView(R.id.seekbar_time_after)
    RangeSeekBar seekbarTimeAfter;
    @BindView(R.id.seekbar_infrared_sensitivity)
    RangeSeekBar seekbarInfraredSensitivity;
    @BindView(R.id.seekbar_pat_sensitivity)
    RangeSeekBar seekbarPatSensitivity;
    @BindView(R.id.rg_checkmode)
    RadioGroup rgCheckmode;
    @BindView(R.id.rg_lightmode)
    RadioGroup rgLightmode;
    @BindView(R.id.rg_voicemode)
    RadioGroup rgVoicemode;
    @BindView(R.id.bt_save)
    Button btSave;

    private int lightBrightness = Constants.LIGHT_BRIGHTNESS;
    private int checkTimeAfter = 0;
    private int infraredSensitivity = Constants.INFRARED_SENSITIVITY;
    private int patSensitivity = Constants.PAT_SENSITIVITY;
    private byte colorAfterCheck = LightCMD.Color.NULL.getByte();
    private byte checkMode = LightCMD.CheckMode.ALL.getByte();
    private byte voiceMode = LightCMD.VoiceMode.STARTVOICE.getByte();
    private byte lightMode = LightCMD.LightMode.NULL.getByte();
    //----------属性设置 end-------

    private LightDao lightDao;
    /**
     * 当前熄灭的灯集合
     */
    private Vector<Integer> offLights;
    /**
     * 点亮的灯集合
     */
    private Vector<IdAndStep> onLights;
    private List<Light> allLights;
    private boolean isStart = false;
    /**
     * 同时亮灯个数 默认8
     */
    private volatile int numberOn = 8;
    /**
     * 灯总数
     */
    private int total;
    /**
     * 点亮灯个数
     */
    volatile int onCount = 0;

    private Random random;
    /**
     * 亮灯指令
     */
    private LightCMD lightCMD;
    /**
     * 执行时间 /分钟 默认2分钟
     */
    private int minute = 2;
    /**
     * 用户触发反应延时
     */
    private int timeCost;

    private byte lightColor = LightCMD.Color.RED.getByte();

    private FragmentManager fragmentManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_lesson1);
        ButterKnife.bind(this);
        initData();
        initView();
        initSettings();
    }

    private void initData() {
        offLights = new Vector<>();
        onLights = new Vector<>();
        lightDao = new LightDao(this);
        random = new Random();
        try {
            allLights = lightDao.getAllLights();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        total = allLights.size();
        fragmentManager = getSupportFragmentManager();
        initProtocolCMD();
    }

    private RadioGroup.OnCheckedChangeListener colorCheckChangeListener = new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {
            switch (checkedId) {
                case R.id.rb_color_hong:
                    lightColor = LightCMD.Color.RED.getByte();
                    cbLightColor.setText("红");
                    break;
                case R.id.rb_color_lv:
                    lightColor = LightCMD.Color.GREEN.getByte();
                    cbLightColor.setText("绿");
                    break;
                case R.id.rb_color_lan:
                    lightColor = LightCMD.Color.BLUE.getByte();
                    cbLightColor.setText("蓝");
                    break;
                case R.id.rb_color_qing:
                    lightColor = LightCMD.Color.QING.getByte();
                    cbLightColor.setText("青");
                    break;
                case R.id.rb_color_zi:
                    lightColor = LightCMD.Color.PURPLE.getByte();
                    cbLightColor.setText("紫");
                    break;
                case R.id.rb_color_huang:
                    lightColor = LightCMD.Color.YELLOW.getByte();
                    cbLightColor.setText("黄");
                    break;
                case R.id.rb_color_bai:
                    lightColor = LightCMD.Color.WHITE.getByte();
                    cbLightColor.setText("白");
                    break;
            }
        }
    };

    private OnRangeChangedListener seekBarChangeListener = new OnRangeChangedListener() {

        @Override
        public void onRangeChanged(RangeSeekBar view, float leftValue, float rightValue, boolean isFromUser) {
            int leftValueInt = (int) leftValue;
            switch (view.getId()) {
                case R.id.seekbar_lightNum:
                    numberOn = leftValueInt;
                    cbLightNum.setIntValue(leftValueInt);
                    seekbarLightNum.setIndicatorText(leftValueInt + "个");
                    break;
                case R.id.seekbar_userNum:
                    cbUserNum.setIntValue(leftValueInt);
                    seekbarUserNum.setIndicatorText(leftValueInt + "人");
                    break;
                case R.id.seekbar_time:
                    minute = leftValueInt;
                    cbTime.setIntValue(leftValueInt);
                    seekbarTime.setIndicatorText(leftValueInt + "分钟");
                    break;
                case R.id.seekbar_stepNum:
                    cbStepNum.setIntValue(leftValueInt);
                    seekbarStepNum.setIndicatorText(leftValueInt + "步");
                    break;
            }
        }

        @Override
        public void onStartTrackingTouch(RangeSeekBar view, boolean isLeft) {

        }

        @Override
        public void onStopTrackingTouch(RangeSeekBar view, boolean isLeft) {

        }
    };

    /*--------------属性设置初始化- start------------*/
    private void initSettings() {
        panel.setInterpolator(new ExpoInterpolator(EasingType.Type.OUT));
        seekbarPatSensitivity.setValue(patSensitivity);
        seekbarInfraredSensitivity.setValue(infraredSensitivity);
        seekbarLightBrightness.setValue(lightBrightness);
        seekbarTimeAfter.setValue(checkTimeAfter);

        seekbarLightBrightness.setOnRangeChangedListener(settingSeekBarChangeListener);
        seekbarTimeAfter.setOnRangeChangedListener(settingSeekBarChangeListener);
        seekbarInfraredSensitivity.setOnRangeChangedListener(settingSeekBarChangeListener);
        seekbarPatSensitivity.setOnRangeChangedListener(settingSeekBarChangeListener);

        rgColorAfter.setOnCheckedChangeListener(settingRadioButtonCheckChangeListener);
        rgCheckmode.setOnCheckedChangeListener(settingRadioButtonCheckChangeListener);
        rgLightmode.setOnCheckedChangeListener(settingRadioButtonCheckChangeListener);
        rgVoicemode.setOnCheckedChangeListener(settingRadioButtonCheckChangeListener);
    }

    @OnClick(R.id.bt_save)
    public void onViewClicked() {
        initProtocolCMD();
        ToastUtils.toastSuccess(this, "保存成功！", 0);
    }

    private void initProtocolCMD() {
        lightCMD = new LightCMD();
        lightCMD.setLightBrightness(lightBrightness)
                .setFinalLightColor(colorAfterCheck)
                .setFinalTimeLast(checkTimeAfter)
                .setInfraredSensitivity(infraredSensitivity)
                .setPatSensitivity(patSensitivity)
                .setCheckMode(checkMode)
                .setLightFlash(lightMode)
                .setLightVoice(voiceMode);
    }

    /**
     * 属性设置中的回调
     */
    private OnRangeChangedListener settingSeekBarChangeListener = new OnRangeChangedListener() {

        @Override
        public void onRangeChanged(RangeSeekBar view, float leftValue, float rightValue, boolean isFromUser) {
            int leftValueInt = (int) leftValue;
            switch (view.getId()) {
                case R.id.seekbar_lightBrightness:
                    lightBrightness = leftValueInt;
                    seekbarLightBrightness.setIndicatorText(leftValueInt + "");
                    break;
                case R.id.seekbar_time_after:
                    checkTimeAfter = leftValueInt;
                    seekbarTimeAfter.setIndicatorText(leftValueInt + "");
                    break;
                case R.id.seekbar_infrared_sensitivity:
                    infraredSensitivity = leftValueInt;
                    seekbarInfraredSensitivity.setIndicatorText(leftValueInt + "");
                    break;
                case R.id.seekbar_pat_sensitivity:
                    patSensitivity = leftValueInt;
                    seekbarPatSensitivity.setIndicatorText(leftValueInt + "");
                    break;
            }
        }

        @Override
        public void onStartTrackingTouch(RangeSeekBar view, boolean isLeft) {

        }

        @Override
        public void onStopTrackingTouch(RangeSeekBar view, boolean isLeft) {

        }
    };

    /**
     * 属性设置radiobutton 回调
     */
    private RadioGroup.OnCheckedChangeListener settingRadioButtonCheckChangeListener = new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {
            switch (checkedId) {
                case R.id.rb_color_hong_after:
                    colorAfterCheck = LightCMD.Color.RED.getByte();
                    break;
                case R.id.rb_color_lv_after:
                    colorAfterCheck = LightCMD.Color.GREEN.getByte();
                    break;
                case R.id.rb_color_lan_after:
                    colorAfterCheck = LightCMD.Color.BLUE.getByte();
                    break;
                case R.id.rb_color_qing_after:
                    colorAfterCheck = LightCMD.Color.QING.getByte();
                    break;
                case R.id.rb_color_zi_after:
                    colorAfterCheck = LightCMD.Color.PURPLE.getByte();
                    break;
                case R.id.rb_color_huang_after:
                    colorAfterCheck = LightCMD.Color.YELLOW.getByte();
                    break;
                case R.id.rb_color_bai_after:
                    colorAfterCheck = LightCMD.Color.WHITE.getByte();
                    break;
                case R.id.rb_color_null_after:
                    colorAfterCheck = LightCMD.Color.NULL.getByte();
                    break;
                case R.id.rb_checkmode_all:
                    checkMode = LightCMD.CheckMode.ALL.getByte();
                    break;
                case R.id.rb_checkmode_infrared:
                    checkMode = LightCMD.CheckMode.Infrared.getByte();
                    break;
                case R.id.rb_checkmode_pat:
                    checkMode = LightCMD.CheckMode.PAT.getByte();
                    break;
                case R.id.rb_lightmode_all:
                    lightMode = LightCMD.LightMode.ALLLIGHT.getByte();
                    break;
                case R.id.rb_lightmode_start:
                    lightMode = LightCMD.LightMode.STARTLIGHT.getByte();
                    break;
                case R.id.rb_lightmode_null:
                    lightMode = LightCMD.LightMode.NULL.getByte();
                    break;
                case R.id.rb_voicemode_check:
                    voiceMode = LightCMD.VoiceMode.SENSEVOICE.getByte();
                    break;
                case R.id.rb_voicemode_start:
                    voiceMode = LightCMD.VoiceMode.STARTVOICE.getByte();
                    break;
                case R.id.rb_voicemode_null:
                    voiceMode = LightCMD.VoiceMode.NULL.getByte();
                    break;
            }
        }
    };



    /*--------------属性设置初始化-end------------*/

    private void initView() {
        cbTime.setIntValue(minute);
        seekbarTime.setValue(minute);
        seekbarLightNum.setValue(8f);
        seekbarLightNum.setOnRangeChangedListener(seekBarChangeListener);
        seekbarStepNum.setOnRangeChangedListener(seekBarChangeListener);
        seekbarTime.setOnRangeChangedListener(seekBarChangeListener);
        seekbarUserNum.setOnRangeChangedListener(seekBarChangeListener);
        rgColor.setOnCheckedChangeListener(colorCheckChangeListener);
    }


    @OnClick(R.id.playView)
    public void clickRunButton(View view) {
        if (!isStart) {
            startRun();
        } else {
            stopRun();
        }
    }

    private boolean isShow = false;

    @OnClick(R.id.ib_show)
    public void clickShowButton(View view) {
        //正在执行 不允许预演
        if (isStart) {
            return;
        }
        if (!isShow) {
            //show
            isShow = true;
            ibShow.setImageResource(R.drawable.hand_stop);
            //todo 开启预演
            writeSerialByte(lightCMD.setLightColor(lightColor).setLight(1).getBytes());
            writeSerialByte(lightCMD.setLightColor(lightColor).setLight(2).getBytes());
            writeSerialByte(lightCMD.setLightColor(lightColor).setLight(3).getBytes());
            writeSerialByte(lightCMD.setLightColor(lightColor).setLight(4).getBytes());
            writeSerialByte(lightCMD.setLightColor(lightColor).setLight(5).getBytes());
            writeSerialByte(lightCMD.setLightColor(lightColor).setLight(6).getBytes());
            writeSerialByte(lightCMD.setLightColor(lightColor).setLight(7).getBytes());
            writeSerialByte(lightCMD.setLightColor(lightColor).setLight(8).getBytes());
        } else {
            //close
            closeAllLight();
            ibShow.setImageResource(R.drawable.hand_start);
            isShow = false;
        }
    }

    @Override
    public void startRun() {
        //todo 输入校验
        if (numberOn>total){
            ToastUtils.toastError(this, "同时亮灯数量必须小于灯总数", 0);
            playView.setChecked(false);
            return;
        }
        if (minute <= 0) {
            UIUtils.showToastSafe("时间必须大于0");
            playView.setChecked(false);
            return;
        }
        if (isShow) {
            UIUtils.showToastSafe("请先结束预演！");
            playView.setChecked(false);
            return;
        }
        super.startRun();
        offLights.clear();
        for (int i = 0; i < total; i++) {
            offLights.add(allLights.get(i).getLightId());
        }
        stepCount = 0;
        timeCost = 0;
        isStart = true;
        startGame();
        countdownTime = (minute * 60) * 1000;
        countdownTime();
    }

    private void closeAllLight(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i=1;i<=16;i++){
                    writeSerialByte(new LightCMD_Close().setLight(i).getBytes());
                }
            }
        }).start();
    }

    @Override
    public void stopRun() {
        super.stopRun();
        isStart = false;
        onLights.clear();
        onCount = 0;
        playView.setChecked(false);
        //关闭灯
        closeAllLight();
        if (null != timer) {
            timer.cancel();
            timer = null;
            tvTimeCountDown.setText("00分00秒");
        }
        DegreeDialog_lesson1 degreeDialog_lesson1 = new DegreeDialog_lesson1();
        degreeDialog_lesson1.setCancelable(false);
        Bundle bundle = new Bundle();
        bundle.putInt("success", stepCount);
//        bundle.putInt("time", timeCost / 1000);
        bundle.putInt("time", timeCost);
        bundle.putInt("faild", 0);
        degreeDialog_lesson1.setArguments(bundle);
        degreeDialog_lesson1.show(fragmentManager, "dialog");
    }

    private CountDownTimer timer;
    private long countdownTime;

    //倒计时的方法
    private void countdownTime() {
        timer = new CountDownTimer(countdownTime, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                //todo 显示时间
                String s = TimeUtils.convertToDifftime(TimeUtils.FORMAT_DAY_CN_3, millisUntilFinished);
                tvTimeCountDown.setText(s);
            }

            @Override
            public void onFinish() {
                stopRun();
            }
        }.start();
    }

    int stepCount = 0;

    public void startGame() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    if (!isStart) {
                        break;
                    }
                    if (onCount < numberOn) {
                        lightOn();
                    }
                }
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    /**
     * 随机点亮一个灯
     */
    public synchronized void lightOn() {
        if (!isStart) {
            return;
        }
        stepCount++;
        int index = random.nextInt(total - onCount);
        Integer lightId = offLights.remove(index);
        int stepNo = stepCount % 255;
        onLights.add(new IdAndStep(lightId, stepNo));
        writeSerialByte(lightCMD
                .setStepNum(stepNo).setLightColor(lightColor).setLight(lightId).getBytes());
        onCount++;
    }

    @Override
    public void onSerialReceivedData(byte[] data) {
        if (data.length < 6) {
            UIUtils.showToastSafe("数据长度错误,请检测使用环境");
            return;
        }
        if (data[5] == CommandType.COMMAND_LIGHT_R) {//亮灯触发回复
            if (isStart) {
                parseLightR(data);
            }
        }
    }

    private synchronized void parseLightR(byte[] data) {
        //触发的light
        int lightId = data[4] & 0xff;
        //触发耗时 ms
        int time = ((data[11] & 0xff) << 24) | ((data[10] & 0xff) << 16) | ((data[9] & 0xff) << 8) | (data[8] & 0xff);
        //触发源
        byte source = data[6];
        //步骤码
        int stepNumber = data[7] & 0xff;
        IdAndStep idAndStep = new IdAndStep(lightId, stepNumber);
        if (onLights.remove(idAndStep)) {
            timeCost += time;
            offLights.add(Integer.valueOf(lightId));
            onCount--;
        } else {
//            UIUtils.showToastSafe(idAndStep.toString());
        }
    }

    @Override
    public String returnToolBarTitle() {
        return "";
    }

}
